home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / OpenGL / OPENGL2.EXE / _SETUP.1 / cube.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-21  |  7.1 KB  |  290 lines

  1. #include <windows.h>
  2. #include <GL/gl.h>
  3.  
  4. char *className = "OpenGL";
  5. char *windowName = "OpenGL Cube";
  6. int winX = 0, winY = 0;
  7. int winWidth = 300, winHeight = 300;
  8.  
  9. HDC hDC;
  10. HGLRC hGLRC;
  11. HPALETTE hPalette;
  12.  
  13. void
  14. init(void)
  15. {
  16.     /* set viewing projection */
  17.     glMatrixMode(GL_PROJECTION);
  18.     glFrustum(-0.5F, 0.5F, -0.5F, 0.5F, 1.0F, 3.0F);
  19.  
  20.     /* position viewer */
  21.     glMatrixMode(GL_MODELVIEW);
  22.     glTranslatef(0.0F, 0.0F, -2.0F);
  23.  
  24.     /* position object */
  25.     glRotatef(30.0F, 1.0F, 0.0F, 0.0F);
  26.     glRotatef(30.0F, 0.0F, 1.0F, 0.0F);
  27.  
  28.     glEnable(GL_DEPTH_TEST);
  29.     glEnable(GL_LIGHTING);
  30.     glEnable(GL_LIGHT0);
  31. }
  32.  
  33. void
  34. redraw(void)
  35. {
  36.     /* clear color and depth buffers */
  37.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  38.  
  39.     /* draw six faces of a cube */
  40.     glBegin(GL_QUADS);
  41.     glNormal3f( 0.0F, 0.0F, 1.0F);
  42.     glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F, 0.5F);
  43.     glVertex3f(-0.5F,-0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F);
  44.  
  45.     glNormal3f( 0.0F, 0.0F,-1.0F);
  46.     glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F, 0.5F,-0.5F);
  47.     glVertex3f( 0.5F, 0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F);
  48.  
  49.     glNormal3f( 0.0F, 1.0F, 0.0F);
  50.     glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F, 0.5F,-0.5F);
  51.     glVertex3f(-0.5F, 0.5F,-0.5F); glVertex3f(-0.5F, 0.5F, 0.5F);
  52.  
  53.     glNormal3f( 0.0F,-1.0F, 0.0F);
  54.     glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F);
  55.     glVertex3f( 0.5F,-0.5F, 0.5F); glVertex3f(-0.5F,-0.5F, 0.5F);
  56.  
  57.     glNormal3f( 1.0F, 0.0F, 0.0F);
  58.     glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F);
  59.     glVertex3f( 0.5F,-0.5F,-0.5F); glVertex3f( 0.5F, 0.5F,-0.5F);
  60.  
  61.     glNormal3f(-1.0F, 0.0F, 0.0F);
  62.     glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F,-0.5F, 0.5F);
  63.     glVertex3f(-0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F,-0.5F);
  64.     glEnd();
  65.  
  66.     SwapBuffers(hDC);
  67. }
  68.  
  69. void
  70. resize(void)
  71. {
  72.     /* set viewport to cover the window */
  73.     glViewport(0, 0, winWidth, winHeight);
  74. }
  75.  
  76. void
  77. setupPixelFormat(HDC hDC)
  78. {
  79.     PIXELFORMATDESCRIPTOR pfd = {
  80.     sizeof(PIXELFORMATDESCRIPTOR),    /* size */
  81.     1,                /* version */
  82.     PFD_SUPPORT_OPENGL |
  83.     PFD_DRAW_TO_WINDOW |
  84.     PFD_DOUBLEBUFFER,        /* support double-buffering */
  85.     PFD_TYPE_RGBA,            /* color type */
  86.     16,                /* prefered color depth */
  87.     0, 0, 0, 0, 0, 0,        /* color bits (ignored) */
  88.     0,                /* no alpha buffer */
  89.     0,                /* alpha bits (ignored) */
  90.     0,                /* no accumulation buffer */
  91.     0, 0, 0, 0,            /* accum bits (ignored) */
  92.     16,                /* depth buffer */
  93.     0,                /* no stencil buffer */
  94.     0,                /* no auxiliary buffers */
  95.     PFD_MAIN_PLANE,            /* main layer */
  96.     0,                /* reserved */
  97.     0, 0, 0,            /* no layer, visible, damage masks */
  98.     };
  99.     int pixelFormat;
  100.  
  101.     pixelFormat = ChoosePixelFormat(hDC, &pfd);
  102.     if (pixelFormat == 0) {
  103.     MessageBox(WindowFromDC(hDC), "ChoosePixelFormat failed.", "Error",
  104.         MB_ICONERROR | MB_OK);
  105.     exit(1);
  106.     }
  107.  
  108.     if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
  109.     MessageBox(WindowFromDC(hDC), "SetPixelFormat failed.", "Error",
  110.         MB_ICONERROR | MB_OK);
  111.     exit(1);
  112.     }
  113. }
  114.  
  115. void
  116. setupPalette(HDC hDC)
  117. {
  118.     int pixelFormat = GetPixelFormat(hDC);
  119.     PIXELFORMATDESCRIPTOR pfd;
  120.     LOGPALETTE* pPal;
  121.     int paletteSize;
  122.  
  123.     DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  124.  
  125.     if (pfd.dwFlags & PFD_NEED_PALETTE) {
  126.     paletteSize = 1 << pfd.cColorBits;
  127.     } else {
  128.     return;
  129.     }
  130.  
  131.     pPal = (LOGPALETTE*)
  132.     malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
  133.     pPal->palVersion = 0x300;
  134.     pPal->palNumEntries = paletteSize;
  135.  
  136.     /* build a simple RGB color palette */
  137.     {
  138.     int redMask = (1 << pfd.cRedBits) - 1;
  139.     int greenMask = (1 << pfd.cGreenBits) - 1;
  140.     int blueMask = (1 << pfd.cBlueBits) - 1;
  141.     int i;
  142.  
  143.     for (i=0; i<paletteSize; ++i) {
  144.         pPal->palPalEntry[i].peRed =
  145.             (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
  146.         pPal->palPalEntry[i].peGreen =
  147.             (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
  148.         pPal->palPalEntry[i].peBlue =
  149.             (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
  150.         pPal->palPalEntry[i].peFlags = 0;
  151.     }
  152.     }
  153.  
  154.     hPalette = CreatePalette(pPal);
  155.     free(pPal);
  156.  
  157.     if (hPalette) {
  158.     SelectPalette(hDC, hPalette, FALSE);
  159.     RealizePalette(hDC);
  160.     }
  161. }
  162.  
  163. LRESULT APIENTRY
  164. WndProc(
  165.     HWND hWnd,
  166.     UINT message,
  167.     WPARAM wParam,
  168.     LPARAM lParam)
  169. {
  170.     switch (message) {
  171.     case WM_CREATE:
  172.     /* initialize OpenGL rendering */
  173.     hDC = GetDC(hWnd);
  174.     setupPixelFormat(hDC);
  175.     setupPalette(hDC);
  176.     hGLRC = wglCreateContext(hDC);
  177.     wglMakeCurrent(hDC, hGLRC);
  178.     init();
  179.     return 0;
  180.     case WM_DESTROY:
  181.     /* finish OpenGL rendering */
  182.     if (hGLRC) {
  183.         wglMakeCurrent(NULL, NULL);
  184.         wglDeleteContext(hGLRC);
  185.     }
  186.     if (hPalette) {
  187.         DeleteObject(hPalette);
  188.     }
  189.     ReleaseDC(hWnd, hDC);
  190.     PostQuitMessage(0);
  191.     return 0;
  192.     case WM_SIZE:
  193.     /* track window size changes */
  194.     if (hGLRC) {
  195.         winWidth = (int) LOWORD(lParam);
  196.         winHeight = (int) HIWORD(lParam);
  197.         resize();
  198.         return 0;
  199.     }
  200.     case WM_PALETTECHANGED:
  201.     /* realize palette if this is *not* the current window */
  202.     if (hGLRC && hPalette && (HWND) wParam != hWnd) {
  203.         UnrealizeObject(hPalette);
  204.         SelectPalette(hDC, hPalette, FALSE);
  205.         RealizePalette(hDC);
  206.         redraw();
  207.         break;
  208.     }
  209.     break;
  210.     case WM_QUERYNEWPALETTE:
  211.     /* realize palette if this is the current window */
  212.     if (hGLRC && hPalette) {
  213.         UnrealizeObject(hPalette);
  214.         SelectPalette(hDC, hPalette, FALSE);
  215.         RealizePalette(hDC);
  216.         redraw();
  217.         return TRUE;
  218.     }
  219.     break;
  220.     case WM_PAINT:
  221.     {
  222.         PAINTSTRUCT ps;
  223.         BeginPaint(hWnd, &ps);
  224.         if (hGLRC) {
  225.         redraw();
  226.         }
  227.         EndPaint(hWnd, &ps);
  228.         return 0;
  229.     }
  230.     break;
  231.     case WM_CHAR:
  232.     /* handle keyboard input */
  233.     switch ((int)wParam) {
  234.     case VK_ESCAPE:
  235.         DestroyWindow(hWnd);
  236.         return 0;
  237.     default:
  238.         break;
  239.     }
  240.     break;
  241.     default:
  242.     break;
  243.     }
  244.     return DefWindowProc(hWnd, message, wParam, lParam);
  245. }
  246.  
  247. int APIENTRY
  248. WinMain(
  249.     HINSTANCE hCurrentInst,
  250.     HINSTANCE hPreviousInst,
  251.     LPSTR lpszCmdLine,
  252.     int nCmdShow)
  253. {
  254.     WNDCLASS wndClass;
  255.     HWND hWnd;
  256.     MSG msg;
  257.  
  258.     /* register window class */
  259.     wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  260.     wndClass.lpfnWndProc = WndProc;
  261.     wndClass.cbClsExtra = 0;
  262.     wndClass.cbWndExtra = 0;
  263.     wndClass.hInstance = hCurrentInst;
  264.     wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  265.     wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  266.     wndClass.hbrBackground = GetStockObject(BLACK_BRUSH);
  267.     wndClass.lpszMenuName = NULL;
  268.     wndClass.lpszClassName = className;
  269.     RegisterClass(&wndClass);
  270.  
  271.     /* create window */
  272.     hWnd = CreateWindow(
  273.     className, windowName,
  274.     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  275.     winX, winY, winWidth, winHeight,
  276.     NULL, NULL, hCurrentInst, NULL);
  277.  
  278.     /* display window */
  279.     ShowWindow(hWnd, nCmdShow);
  280.     UpdateWindow(hWnd);
  281.  
  282.     /* process messages */
  283.     while (GetMessage(&msg, NULL, 0, 0) == TRUE) {
  284.     TranslateMessage(&msg);
  285.     DispatchMessage(&msg);
  286.     }
  287.     return msg.wParam;
  288. }
  289. 
  290.